#ifndef CI_TASK_H
#define CI_TASK_H

#include <malloc.h>

#include "aceMesh_runtime.h"
#include "aceMesh_task.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct ci_task {
    struct aceMesh_task aceMesh_task_base;
    void *ci_args;  // __attribute__((aligned(64)));
#ifdef DOUBLE_FUNC
    TASK_FUNCPTR master_ci_task_func;  // __attribute__((aligned(32)));
#endif
    TASK_FUNCPTR slave_ci_task_func;  // __attribute__((aligned(64)));
    void *ci_cxx_this_pointer;
    void *ci_get_neighbors;
    void *ci_neighbor_args;
    int neighbor_isdefine;
} ci_task;

#ifdef DOUBLE_FUNC
void ci_task_constructor_msfunc(ci_task *self, TASK_FUNCPTR mfuncptr, TASK_FUNCPTR sfuncptr);
#endif
void ci_task_constructor(ci_task *self, TASK_FUNCPTR funcptr);
void ci_task_destructor(ci_task *p_ci_task);
void define(ci_task *self, void *a_args, unsigned int args_size);
void define_neighbors(ci_task *self, void *cxx_this_pointer, void *a_get_neighbors,
                      void *a_neighbor_args);
//void get_neighbor(ci_task *self, int neighbor, void *src_addr, void **neighbor_addrs,
  //                int *num_neigh);
void get_neighbor(ci_task *self, void **neighbor_addrs, int *num_neigh);
void slave_ci_task_constructor(ci_task *self, TASK_FUNCPTR funcptr);
void slave_ci_task_destructor(ci_task *p_ci_task);
void slave_define(ci_task *self, void *a_args, unsigned int args_size);
void slave_define_neighbors(ci_task *self, void *cxx_this_pointer, void *a_get_neighbors,
                            void *a_neighbor_args);
//void slave_get_neighbor(ci_task *self, int neighbor, void *src_addr, void **neighbor_addrs,
      //                  int *num_neigh);
void slave_get_neighbor(ci_task *self, void **neighbor_addrs,
                        int *num_neigh);   
#ifdef __cplusplus
}
#endif

#endif
